
<?php
/*


this class encapsulates the PHP mail() function.
implements CC, Bcc, Priority headers


@version	1.3 

- added ReplyTo( $address ) method
- added Receipt() method - to add a mail receipt
- added optionnal charset parameter to Body() method. this should fix charset problem on some mail clients

@example

include "libmail.php";

$m= new Mail; // create the mail
$m->From( "leo@isp.com" );
$m->To( "destination@somewhere.fr" );
$m->Subject( "the subject of the mail" );	

$message= "Hello world!\nthis is a test of the Mail class\nplease ignore\nThanks.";
$m->Body( $message);	// set the body
$m->Cc( "someone@somewhere.fr");
$m->Bcc( "someoneelse@somewhere.fr");
$m->Priority(4) ;	// set the priority to Low 
$m->Attach( "/home/leo/toto.gif", "image/gif" ) ;	// attach a file of type image/gif
$m->Send();	// send the mail
echo "the mail below has been sent:<br><pre>", $m->Get(), "</pre>";


LASTMOD
Fri Oct  6 15:46:12 UTC 2000

@author	Leo West - lwest@free.fr

*/

class Mail
{
  var $sendtoex = array();
  var $sendto = array();
  var $acc = array();
  var $abcc = array();
  var $aattach = array();
  var $fattach = array();
  var $xheaders = array();
  var $priorities = array('1 (Highest)', '2 (High)', '3 (Normal)', '4 (Low)', '5 (Lowest)');
  var $charset = "us-ascii";
  var $ctencoding = "7bit";
  var $boundary;
  var $receipt = 0;
  
  function Mail(){
    $this->boundary = "--" . md5(uniqid("myboundary"));
  }
  
  function Subject($subject = ""){
    $this->xheaders['Subject'] = strtr($subject, "\r\n", "  ");
    return true;
  }
  
  function From($from_email, $from_name = ""){
    if (!is_string($from_email)) {
      return false;
    } //!is_string($from_email)
    
    if (empty($from_name)) {
      $this->xheaders['From'] = $from_email;
    } //empty($from_name)
    else {
      $this->xheaders['From'] = "\"$from_name\" <$from_email>";
    }
    
    return true;
  }
  
  function ReplyTo($replyto_email, $replyto_name = ""){
    if (!is_string($replyto_email)) {
      return false;
    } //!is_string($replyto_email)
    
    if (empty($replyto_email)) {
      $this->xheaders['Reply-To'] = $replyto_email;
    } //empty($replyto_email)
    else {
      $this->xheaders['Reply-To'] = "\"$replyto_name\" <$replyto_email>";
    }
    
    return true;
  }
  
  function ReturnPath($returnpath_email, $returnpath_name = ""){
    if (!is_string($returnpath_email)) {
      return false;
    } //!is_string($returnpath_email)
    
    if (empty($returnpath_email)) {
      $this->xheaders['Return-Path'] = $returnpath_email;
    } //empty($returnpath_email)
    else {
      $this->xheaders['Return-Path'] = "\"$returnpath_name\" <$returnpath_email>";
    }
    
    return true;
  }
  
  function Receipt(){
    $this->receipt = 1;
    return true;
  }
  
  function To($address){
    if (is_array($address)) {
      $this->sendto   = array();
      $this->sendtoex = array();
      
      foreach ($address as $key => $value) {
        if (is_numeric($key)) {
          $this->sendto[]   = $value;
          $this->sendtoex[] = $value;
        } //is_numeric($key)
        elseif (is_string($key) && is_string($value)) {
          $value            = trim(str_replace('"', '', $value));
          $this->sendto[]   = $key;
          $this->sendtoex[] = "\"$value\" <$key>";
        } //is_string($key) && is_string($value)
      } //$address as $key => $value
    } //is_array($address)
    else {
      $this->sendto[]   = $address;
      $this->sendtoex[] = $address;
    }
    
    return true;
  }
  
  function Cc($address)  {
    if (is_array($address)) {
      $this->acc = array();
      foreach ($address as $key => $value) {
        if (is_numeric($key)) {
          $this->acc[] = $value;
        } //is_numeric($key)
        elseif (is_string($key) && is_string($value)) {
          $value       = str_replace('"', '', $value);
          $this->acc[] = "\"$value\" <$key>";
        } //is_string($key) && is_string($value)
      } //$address as $key => $value
    } //is_array($address)
    else {
      $this->acc = array(
        $address
      );
    }
    
    return true;
  }
  
  function Bcc($address)  {
    if (is_array($address)) {
      $this->abcc = array();
      foreach ($address as $key => $value) {
        if (is_numeric($key)) {
          $this->abcc[] = $value;
        } //is_numeric($key)
        elseif (is_string($key) && is_string($value)) {
          $value        = str_replace('"', '', $value);
          $this->abcc[] = "\"$value\" <$key>";
        } //is_string($key) && is_string($value)
      } //$address as $key => $value
    } //is_array($address)
    else {
      $this->abcc = array(
        $address
      );
    }
    return true;
  }
  
  function Body($body = "", $charset = ""){
    $this->body = $body;
    if (!empty($charset)) {
      $this->charset = strtolower($charset);
      if ($this->charset != "us-ascii") {
        $this->ctencoding = "8bit";
      } //$this->charset != "us-ascii"
    } //!empty($charset)
    return true;
  }
  
  function Organization($org = "") {
    if (!empty($org)) {
      $this->xheaders['Organization'] = $org;
    } //!empty($org)
    return true;
  }
  
  function AntiSpaming($client_ip = "", $proxy_server = "", $user_agent = "")  {
    if (empty($client_ip)) {
      if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $client_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
      } //isset($_SERVER['HTTP_X_FORWARDED_FOR'])
      elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
        $client_ip = $_SERVER['HTTP_CLIENT_IP'];
      } //isset($_SERVER['HTTP_CLIENT_IP'])
        elseif (isset($_SERVER['HTTP_FROM '])) {
        $client_ip = $_SERVER['HTTP_FROM'];
      } //isset($_SERVER['HTTP_FROM '])
        elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $client_ip = $_SERVER['REMOTE_ADDR'];
      } //isset($_SERVER['REMOTE_ADDR'])
      $this->xheaders['X-HTTP-Posting-Host'] = $client_ip;
    } //empty($client_ip)
    else {
      $this->xheaders['X-HTTP-Posting-Host'] = $client_ip;
    }
    if (empty($proxy_server)) {
      if ($client_ip != $_SERVER['REMOTE_ADDR']) {
        $this->xheaders['X-HTTP-Proxy-Server'] = $_SERVER['REMOTE_ADDR'];
      } //$client_ip != $_SERVER['REMOTE_ADDR']
    } //empty($proxy_server)
    else {
      $this->xheaders['X-HTTP-Proxy-Server'] = $proxy_server;
    }
    if (empty($user_agent)) {
      if (isset($_SERVER['HTTP_USER_AGENT'])) {
        $this->xheaders['X-HTTP-Posting-UserAgent'] = $_SERVER['HTTP_USER_AGENT'];
      } //isset($_SERVER['HTTP_USER_AGENT'])
      else {
        $this->xheaders['X-HTTP-Posting-UserAgent'] = "Unknown";
      }
    } //empty($user_agent)
    else {
      $this->xheaders['X-HTTP-Posting-UserAgent'] = $user_agent;
    }
    return true;
  }
  
  function Priority($priority = 3) {
    if (!isset($this->priorities[$priority - 1])) {
      return false;
    } //!isset($this->priorities[$priority - 1])
    $this->xheaders["X-Priority"] = $this->priorities[$priority - 1];
    return true;
  }
  
  function Attach($filepath, $mimetype = "", $disposition = "inline", $filename = "")  {
    if (empty($filepath)) {
      return false;
    } //empty($filepath)
    if (empty($mimetype)) {
      $mimetype = "application/x-unknown-content-type";
    } //empty($mimetype)
    if (empty($filename)) {
      $filename = basename($filepath);
    } //empty($filename)
    $this->fattach[] = $filename;
    $this->aattach[] = $filepath;
    $this->actype[]  = $mimetype;
    $this->adispo[]  = $disposition;
    return true;
  }
  
  function BuildMail()
  {
    $this->headers = "";
    if (count($this->sendtoex) > 0) {
      $this->xheaders['To'] = implode(", ", $this->sendtoex);
    } //count($this->sendtoex) > 0
    if (count($this->acc) > 0) {
      $this->xheaders['CC'] = implode(", ", $this->acc);
    } //count($this->acc) > 0
    if (count($this->abcc) > 0) {
      $this->xheaders['BCC'] = implode(", ", $this->abcc);
    } //count($this->abcc) > 0
    if ($this->receipt) {
      if (isset($this->xheaders["Reply-To"])) {
        $this->xheaders["Disposition-Notification-To"] = $this->xheaders["Reply-To"];
      } //isset($this->xheaders["Reply-To"])
      else {
        $this->xheaders["Disposition-Notification-To"] = $this->xheaders['From'];
      }
    } //$this->receipt
    if ($this->charset != "") {
      $this->xheaders["Mime-Version"]              = "1.0";
      $this->xheaders["Content-Type"]              = "text/html; charset=$this->charset";
      $this->xheaders["Content-Transfer-Encoding"] = $this->ctencoding;
    } //$this->charset != ""
    $this->xheaders["X-Mailer"] = "Php/libMailv2.1";
    if (count($this->aattach) > 0) {
      $this->_build_attachement();
    } //count($this->aattach) > 0
    else {
      $this->fullBody = $this->body;
    }
    reset($this->xheaders);
    while (list($hdr, $value) = each($this->xheaders)) {
      if ($hdr != "Subject") {
        $this->headers .= "$hdr: $value\n";
      } //$hdr != "Subject"
    } //list($hdr, $value) = each($this->xheaders)
    return true;
  }
  
  function Send()
  {
    $this->BuildMail();
    $strTo = implode(", ", $this->sendto);
    return mail($strTo, $this->xheaders['Subject'], $this->fullBody, $this->headers);
  }
  
  function Get()
  {
    $this->BuildMail();
    $mail = $this->headers . "\n";
    $mail .= $this->fullBody;
    return $mail;
  }
  
  function _build_attachement()
  {
    $this->xheaders["Content-Type"] = "multipart/mixed;\n boundary=\"$this->boundary\"";
    $this->fullBody                 = "This is a multi-part message in MIME format.\n--$this->boundary\n";
    $this->fullBody .= "Content-Type: text/html; charset=$this->charset\nContent-Transfer-Encoding: $this->ctencoding\n\n" . $this->body . "\n";
    $sep = chr(13) . chr(10);
    $ata = array();
    $k   = 0;
    for ($i = 0; $i < count($this->aattach); $i++) {
      $filename    = $this->aattach[$i];
      $basename    = basename($this->fattach[$i]);
      $ctype       = $this->actype[$i]; // content-type
      $disposition = $this->adispo[$i];
      if (!file_exists($filename)) {
        return false;
      } //!file_exists($filename)
      $subhdr    = "--$this->boundary\nContent-type: $ctype;\n name=\"$basename\"\nContent-Transfer-Encoding: base64\nContent-Disposition: $disposition;\n  filename=\"$basename\"\n";
      $ata[$k++] = $subhdr;
      $linesz    = filesize($filename) + 1;
      $fp        = fopen($filename, 'rb');
      $ata[$k++] = chunk_split(base64_encode(fread($fp, $linesz)));
      fclose($fp);
    } //$i = 0; $i < count($this->aattach); $i++
    $this->fullBody .= implode($sep, $ata);
  }
} // class Mail
?>
